/*
 * "Hello World" example.
 *
 * This example prints 'Hello from Nios II' to the STDOUT stream. It runs on
 * the Nios II 'standard', 'full_featured', 'fast', and 'low_cost' example
 * designs. It runs with or without the MicroC/OS-II RTOS and requires a STDOUT
 * device in your system's hardware.
 * The memory footprint of this hosted application is ~69 kbytes by default
 * using the standard reference design.
 *
 * For a reduced footprint version of this template, and an explanation of how
 * to reduce the memory footprint for a given application, see the
 * "small_hello_world" template.
 *
 */

#include <stdio.h>
#include <system.h>
#include <unistd.h>
#include <altera_avalon_pio_regs.h>
#include <altera_avalon_timer_regs.h>
#include <sys/alt_irq.h>
#include <alt_types.h>
#include <io.h>

#define IOWR_AVALON_SEGLED_DATA(base,data)     IOWR(base, 0, data)


void KEY_IRQ_Init(void);
void KEY_IRQ_Interrupt_Control(void);
void KEY_IRQ_Interrupt_Up(void);
void KEY_IRQ_Interrupt_Down(void);
void TIMER_IRQ_Init(void);
void TIMER_IRQ_Interrupt(void);

alt_u32 timer_isr_context;
alt_u32 tomato_clock = 25*60;
alt_u32 clock_backup = 0;
alt_u8 is_start = 0;
alt_u8 beep_start = 0;
alt_u8 beep_count = 0;
int main()
{
	KEY_IRQ_Init();
	TIMER_IRQ_Init();
	while (1)
	{
		IOWR_AVALON_SEGLED_DATA(AVALON_DTUBE_0_BASE, tomato_clock);
		if (tomato_clock == 0)
		{
			is_start = 0;
		}
	}

  	 return 0;
}

void KEY_IRQ_Init(void)
{
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_CONTROL_BASE, 1);
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_DOWN_BASE, 1);
	IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_UP_BASE, 1);

	alt_ic_isr_register(PIO_CONTROL_IRQ_INTERRUPT_CONTROLLER_ID,
			PIO_CONTROL_IRQ,
			&KEY_IRQ_Interrupt_Control,
			0,
			0);
	alt_ic_isr_register(PIO_UP_IRQ_INTERRUPT_CONTROLLER_ID,
			PIO_UP_IRQ,
			&KEY_IRQ_Interrupt_Up,
			0,
			0);
	alt_ic_isr_register(PIO_DOWN_IRQ_INTERRUPT_CONTROLLER_ID,
			PIO_DOWN_IRQ,
			&KEY_IRQ_Interrupt_Down,
			0,
			0);

}

void KEY_IRQ_Interrupt_Control(void)
{
	usleep(1000*500);
	if (is_start == 0)
	{
		is_start = 1;
		clock_backup = tomato_clock;
	}
	else if (is_start == 1)
	{
		is_start = 0;
	}
	IOWR_AVALON_SEGLED_DATA(AVALON_DTUBE_0_BASE, tomato_clock);
}

void KEY_IRQ_Interrupt_Up(void)
{
	usleep(1000*500);
	if (is_start == 0)
	{
		if (tomato_clock % 60 != 0)
		{
			tomato_clock = tomato_clock - tomato_clock % 60;
		}
		else
		{
			tomato_clock += 1*60;
			if (tomato_clock > 45 *60)
			{
				tomato_clock = 45 *60;
			}
		}
		IOWR_AVALON_SEGLED_DATA(AVALON_DTUBE_0_BASE, tomato_clock);
	}
}

void KEY_IRQ_Interrupt_Down(void)
{
	usleep(1000*500);
	if (is_start == 0)
	{
		if (tomato_clock % 60 != 0)
		{
			tomato_clock = tomato_clock - tomato_clock % 60;
		}
		else
		{
			tomato_clock -= 1*60;
			if (tomato_clock > 45 *60)
			{
				tomato_clock = 0;
			}
		}
		IOWR_AVALON_SEGLED_DATA(AVALON_DTUBE_0_BASE, tomato_clock);
	}

}

void TIMER_IRQ_Init(void)
{
	void* isr_context_ptr = (void*) &timer_isr_context;
	IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_BASE, 0x02FA);
	IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_BASE, 0xF07F);
	IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_BASE,
	ALTERA_AVALON_TIMER_CONTROL_START_MSK |
	ALTERA_AVALON_TIMER_CONTROL_CONT_MSK |
	ALTERA_AVALON_TIMER_CONTROL_ITO_MSK); 
	alt_ic_isr_register(
			TIMER_IRQ_INTERRUPT_CONTROLLER_ID, 
			TIMER_IRQ,                      
			&TIMER_IRQ_Interrupt,             
			isr_context_ptr,             
			0x0);                       
}

void TIMER_IRQ_Interrupt(void)
{
	if (is_start == 1)
	{
		if (tomato_clock-- <= 0)
		{
			tomato_clock = 0;
		}
		if (tomato_clock == 0)
		{
			beep_start = 1;
			IOWR_ALTERA_AVALON_PIO_DATA(PIO_BEEP_BASE, 1);
		}
	}
	if (beep_start == 1)
	{
		beep_count += 1;
		if (beep_count == 30)
		{
			beep_start = 0;
			IOWR_ALTERA_AVALON_PIO_DATA(PIO_BEEP_BASE, 0);
			tomato_clock = clock_backup;
		}
	}

	IOWR_ALTERA_AVALON_TIMER_STATUS(TIMER_BASE,~ALTERA_AVALON_TIMER_STATUS_TO_MSK);
}
